#pragma once

#ifndef __Win32__
#if __PTHREADS__
#if __solaris__ || __sgi__ || __hpux__
#include <errno.h>
#else
#include <sys/errno.h>
#endif
#include <pthread.h>
#else
#include <mach/mach.h>
#include <mach/cthreads.h>
#endif
#include <sys/syscall.h>
#else
#include <process.h>
#endif
#include "OSHeaders.h"
#include <string.h>

class OSThread
{
public:
    OSThread();
    ~OSThread();

    void Start();
    virtual void Entry() = 0;

    static void Sleep(UInt32 milliseconds);
#ifdef WIN32
    static int          GetErrno();
    static DWORD        GetCurrentThreadID() { return GetCurrentThreadId(); }
#else
    static  int         GetErrno() { return errno; }
    static  pthread_t   GetCurrentThreadID() { return ::pthread_self(); }
	
#endif

#ifdef WIN32
	HANDLE         GetSelfID(){ return fThreadID; }
#elif __PTHREADS__
	pthread_t      GetSelfID(){return fThreadID;}
#else
	UInt32         GetSelfID(){return fThreadID;}
#endif
	
    void            Join();
    void            SendStopRequest() { fStopRequested = true; }
    Bool16          IsStopRequested() { return fStopRequested; }
	void            StopAndWaitForThread();

private:
#ifdef __Win32__
    static unsigned int WINAPI _Entry(LPVOID inThread);
#else
    static void*    _Entry(void* inThread);
#endif

    Bool16          SwitchPersonality();

private:
#ifdef __Win32__
    static DWORD    sThreadStorageIndex;
#elif __PTHREADS__
    static pthread_key_t    gMainKey;
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
    //static pthread_attr_t sThreadAttr;
#endif
#endif
    Bool16 fStopRequested;
    Bool16 fJoined;

#ifdef WIN32
    HANDLE          fThreadID;
#elif __PTHREADS__
    pthread_t       fThreadID;
#else
    UInt32          fThreadID;
#endif

};

